/**
 ******************************************************************************
 * @file    linklist_node_t.h
 * @author  Chavis.Chen
 * @version V1.0.0
 * @date    26-Sep-2018
 * @brief   This file contains the common definitions, macros and functions to
 *          be shared throughout the project.
 ******************************************************************************
 *
 *  The MIT License
 *  Copyright (c) 2018 Chavis.Chen.
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a copy
 *  of this software and associated documentation files (the "Software"), to deal
 *  in the Software without restriction, including without limitation the rights
 *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *  copies of the Software, and to permit persons to whom the Software is furnished
 *  to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included in
 *  all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 *  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
 *  IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 ******************************************************************************
 */


#ifndef _LINKLIST_H
#define _LINKLIST_H

#include "common.h"

typedef enum
{
    DIR_FIFO,
    DIR_LIFO
} push_dir_e;

#define DIR_DEFAULT DIR_FIFO

typedef uint8 data_t;

typedef uint32 datasize_t;

typedef uint32 node_cnt_t;

typedef int32 linklist_id_t;

#pragma pack(push)
#pragma pack(1)
typedef struct node
{
	struct node * next;
    datasize_t size;
    data_t data[1];
} linklist_node_t;
#pragma pack(pop)

#pragma pack(push)
#pragma pack(1)
typedef struct
{
    node_cnt_t node_cnt;
    linklist_node_t * header;
    linklist_node_t * tail;
    linklist_node_t * curt;
} linklist_t;
#pragma pack(pop)

typedef linklist_t * linklist_handle_t;

extern OSStatus linklist_init(linklist_handle_t * linklist_handle_ptr);
extern OSStatus linklist_push(linklist_handle_t * linklist_handle_ptr, push_dir_e dir, data_t * data, datasize_t size);
extern OSStatus linklist_pop(linklist_handle_t * linklist_handle_ptr, data_t * * data_pp, datasize_t * data_len);
extern OSStatus linklist_get_node_cnt(linklist_handle_t * linklist_handle_ptr, node_cnt_t * nodeCnt);
extern OSStatus linklist_node_find(linklist_handle_t * linklist_handle_ptr, uint32_t i, linklist_node_t * * dest_node);
extern OSStatus linklist_node_delete(linklist_handle_t * linklist_handle_ptr, uint32_t i);
extern OSStatus linklist_clean(linklist_handle_t * linklist_handle_ptr);
extern OSStatus linklist_deinit(linklist_handle_t * linklist_handle_ptr);
extern void 	linklist_mem_free(void * mem_ptr);

#endif
